package com.os.osframe.scaffold.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * Created by wangchun on 16/7/15.
 */
public class FileToZipUtil {
    static final int BUFFER = 8192;

    /**
     * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的ZIP文件,并存放到zipFilePath。
     * @param sourceFilePath 待压缩的文件路径
     * @param zipFilePath	 压缩后存放路径
     * @param fileName		 压缩后文件的名称
     * @return flag
     */
    public static boolean fileToZip(String sourceFilePath,String zipFilePath,String fileName){
        return fileToZip(sourceFilePath,zipFilePath,fileName,"");
    }
    /**
     * 将存放在sourceFilePath目录下的源文件,打包成fileName名称的ZIP文件,并存放到zipFilePath。
     * @param sourceFilePath 待压缩的文件路径
     * @param zipFilePath	 压缩后存放路径
     * @param fileName		 压缩后文件的名称
     * @return flag
     */
    public static boolean fileToZip(String sourceFilePath,String zipFilePath,String fileName,String baseFolder) {
        boolean flag = false;
        File sourceFile = new File(sourceFilePath);
        File zipFileFolder=new File(zipFilePath);
        ZipOutputStream zos = null;
        if(!zipFileFolder.exists()){
            zipFileFolder.mkdirs();
        }
        FileOutputStream fos = null;
        if(sourceFile.exists() == false) {
            System.out.println(">>>>>> 待压缩的文件目录：" + sourceFilePath + " 不存在. <<<<<<");

        } else {
            try {
                File zipFile = new File(zipFilePath + "/" + fileName + ".zip");
                if(zipFile.exists()) {//当存在文件时，先删除文件，再打包
                    System.out.println(">>>>>> " + zipFilePath + " 目录下存在名字为：" + fileName + ".zip" + " 打包文件. <<<<<<");
                    zipFile.delete();
                }
                fos = new FileOutputStream(zipFile);
                zos = new ZipOutputStream(new BufferedOutputStream(fos));
                compress(sourceFile,zos,baseFolder);
                flag=true;
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                // 关闭流
                try {
                    if(null != zos) zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        }

        return flag;
    }
    private static void compress(File file, ZipOutputStream out, String basedir) {
        //判断是目录还是文件
        if (file.isDirectory()) {
            System.out.println("压缩：" + basedir + file.getName());
            compressDirectory(file, out, basedir);
        } else {
            System.out.println("压缩：" + basedir + file.getName());
            compressFile(file, out, basedir);
        }
    }
    // 压缩一个目录
    private static void compressDirectory(File dir, ZipOutputStream out, String basedir) {
        if (!dir.exists())
            return;
        File[] files = dir.listFiles();
        for (int i = 0; i < files.length; i++) {
            /** 递归 */
            compress(files[i], out, basedir + dir.getName() + "/");
        }
    }
    //压缩一个文件
    private static void compressFile(File file, ZipOutputStream out, String basedir) {
        if (!file.exists()) {
            return;
        }
        try {
            BufferedInputStream bis = new BufferedInputStream(
                    new FileInputStream(file));
            ZipEntry entry = new ZipEntry(basedir + file.getName());
            out.putNextEntry(entry);
            int count;
            byte data[] = new byte[BUFFER];
            while ((count = bis.read(data, 0, BUFFER)) != -1) {
                out.write(data, 0, count);
            }
            bis.close();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 将文件打包成ZIP压缩文件,main方法测试
     * @param args
     */
    public static void main(String[] args) {
        String sourceFilePath = "/Users/wangchun/uploadFile/auto/code/os/news/";
        String zipFilePath = "/Users/wangchun/uploadFile/auto/downloads";
        String fileName = "os.news";

        boolean flag = FileToZipUtil.fileToZip(sourceFilePath, zipFilePath, fileName);
        if(flag) {
            System.out.println(">>>>>> 文件打包成功. <<<<<<");
        } else {
            System.out.println(">>>>>> 文件打包失败. <<<<<<");
        }
    }
}
